// package: rewords-server-2024
// filename: admin
// author: diogoxiang@gmail.com
// time: 2025/1/22 14:56

package admin

import (
	"context"
	"github.com/gogf/gf/v2/errors/gcode"
	"go.mongodb.org/mongo-driver/bson"
	"rewords-server-2024/internal/logic/mgx"
	"rewords-server-2024/internal/model/input/form"
	"rewords-server-2024/utility/ztime"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"

	"rewords-server-2024/api/admin"
	"rewords-server-2024/internal/consts"
	"rewords-server-2024/internal/library/ecode"
	"rewords-server-2024/internal/model/entity"
	"rewords-server-2024/internal/model/input/query_in"
	"rewords-server-2024/internal/service"
	"rewords-server-2024/utility/ufun"
)

var AiCtrl = new(cAi)

type cAi struct{}

func (c *cAi) QueryList(ctx context.Context, req *admin.AiSetListReq) (res *admin.AiSetListRes, err error) {

	query, skip, limit, sortFields, _ := query_in.BuildMongoQueryWithPage(req.Conditions, req.OrderFields, req.Page, nil)
	g.Log().Debug(ctx, "MongoDB query conditions:", query)
	g.Log().Debug(ctx, "Skip:", skip, "Limit:", limit)

	result, err := service.Mgx().Find(ctx, consts.CAiSet, query, nil, skip, limit, sortFields)

	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}
	var datas []entity.SysAiModel
	if err = gconv.Struct(result, &datas); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}
	var total int64

	if req.Page.QueryCount {
		// 获取总记录数
		total, err = service.Mgx().CountDocuments(ctx, consts.CAiSet, query)
		if err != nil {
			return nil, gerror.Wrap(err, "获取总记录数失败")
		}
	}
	res = &admin.AiSetListRes{
		Data: ufun.If(len(datas) > 0, datas, []entity.SysAiModel{}),
		PageResult: query_in.PageResult{
			Current:  (skip / limit) + 1,
			PageSize: limit,
			Total:    total,
			Pages:    (total + limit - 1) / limit,
			HasNext:  (skip + limit) < total,
		},
	}

	return res, nil
}

func (c *cAi) QueryInfo(ctx context.Context, req *admin.AiSetInfoReq) (res *admin.AiSetInfoRes, err error) {

	selectMap := bson.M{
		"id": req.Id,
		//"etype":  "ai_set",
		//"status": "normal",
	}
	result, err := service.Mgx().FindOne(ctx, consts.CAiSet, selectMap, nil)
	if err != nil {
		return nil, gerror.NewCode(gcode.CodeNotImplemented)
	}
	var data entity.SysAiModel

	if err = gconv.Struct(result, &data); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}
	res = &admin.AiSetInfoRes{
		data,
	}

	return
}
func (c *cAi) AddAiSet(ctx context.Context, req *admin.AiSetAddReq) (res *admin.AiSetAddRes, err error) {

	Doc := &entity.SysAiModel{
		//Id:       req.Id,
		ApiKey:   req.ApiKey,
		Name:     req.Name,
		Platform: req.Platform,
		Url:      req.Url,
		MaxToken: req.MaxToken,
		DocUrl:   req.DocUrl,
		Remark:   req.Remark,
		Status:   req.Status,
		Sort:     req.Sort,
		Info:     req.Info,
	}
	eid, err := mgx.GetAutoInc("ai_set")
	if err != nil {
		// 处理错误，例如记录日志或返回错误信息
		g.Log().Printf(ctx, "Failed to get auto increment value for user: %v", err)
		// 根据实际情况决定如何处理错误，例如返回一个错误值或中断程序
		return nil, gerror.NewCode(ecode.InvalidParams)
	}
	Doc.Id = int64(eid)
	Doc.SetTimeValue(0)
	Doc.SetTimeValue(1)
	err = service.Mgx().InsertOne(ctx, consts.CAiSet, Doc)
	if err != nil {
		g.Log().Error(ctx, "Insert error:", err)
		return nil, gerror.NewCode(ecode.InvalidParams)
	}

	// 将 Doc.Id 从 int64 转换为 string
	res = &admin.AiSetAddRes{
		Id: gconv.String(Doc.Id),
	}

	return res, nil

}
func (c *cAi) UpdateAiSet(ctx context.Context, req *admin.AiSetUpdateReq) (res *admin.AiSetUpdateRes, err error) {
	updataDoc := form.NewBuilder().
		SetIfNotEmpty("api_key", req.ApiKey).
		SetIfNotEmpty("name", req.Name).
		SetIfNotEmpty("platform", req.Platform).
		SetIfNotEmpty("url", req.Url).
		SetIfNotEmpty("max_token", req.MaxToken).
		SetIfNotEmpty("doc_url", req.DocUrl).
		SetIfNotEmpty("remark", req.Remark).
		SetIfNotEmpty("status", req.Status).
		SetIfNotEmpty("sort", req.Sort).
		SetIfNotEmpty("info", req.Info).
		Set("updated_at", ztime.GetLocalTime()).
		Build()
	result, err := service.Mgx().UpdateOne(ctx,
		consts.CAiSet,
		bson.M{"id": req.Id},
		bson.M{"$set": updataDoc},
	)

	if err != nil {
		g.Log().Error(ctx, "Update error:", err)
		return nil, gerror.NewCode(ecode.InvalidParams)
	}

	if result.MatchedCount == 0 {
		return nil, gerror.NewCode(ecode.DataNotFound)
	}

	return &admin.AiSetUpdateRes{}, err
}

func (c *cAi) DeleteAiSet(ctx context.Context, req *admin.AiSetDeleteReq) (res *admin.AiSetDeleteRes, err error) {
	updateDoc := form.NewBuilder().
		Set("deleted_at", ztime.GetLocalTime()).
		Build()

	result, err := service.Mgx().UpdateOne(ctx,
		consts.CAiSet,
		bson.M{"id": req.Id},
		bson.M{"$set": updateDoc},
	)

	if err != nil {
		g.Log().Error(ctx, "Delete error:", err)
		return nil, gerror.NewCode(ecode.InvalidParams)
	}

	if result.MatchedCount == 0 {
		return nil, gerror.NewCode(ecode.DataNotFound)
	}

	return &admin.AiSetDeleteRes{}, err
}

func (c *cAi) QueryLogList(ctx context.Context, req *admin.AiModelLogReq) (res *admin.AiModelLogRes, err error) {

	query, skip, limit, sortFields, _ := query_in.BuildMongoQueryWithPage(req.Conditions, req.OrderFields, req.Page, nil)
	g.Log().Debug(ctx, "MongoDB query conditions:", query)
	g.Log().Debug(ctx, "Skip:", skip, "Limit:", limit)

	result, err := service.Mgx().Find(ctx, consts.CAiModelLog, query, nil, skip, limit, sortFields)

	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}

	var datas []entity.SysAiModelLog
	if err = gconv.Struct(result, &datas); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	var total int64

	if req.Page.QueryCount {
		// 获取总记录数
		total, err = service.Mgx().CountDocuments(ctx, consts.CAiModelLog, query)
		if err != nil {
			return nil, gerror.Wrap(err, "获取总记录数失败")
		}
	}

	res = &admin.AiModelLogRes{
		Data: ufun.If(len(datas) > 0, datas, []entity.SysAiModelLog{}),
		PageResult: query_in.PageResult{
			Current:  (skip / limit) + 1,
			PageSize: limit,
			Total:    total,
			Pages:    (total + limit - 1) / limit,
			HasNext:  (skip + limit) < total,
		},
	}

	return res, nil
}
